#!/usr/bin/env python3
# Copyright (c) 2021, the R8 project authors. Please see the AUTHORS file
# for details. All rights reserved. Use of this source code is governed by a
# BSD-style license that can be found in the LICENSE file.

import argparse
import jdk
import os.path
import re
import subprocess
import sys
import urllib.request

import utils

# Grep match string for 'Version X.Y.Z[-dev]'
VERSION_EXP='^Version [[:digit:]]\+.[[:digit:]]\+.[[:digit:]]\+\(\|-dev\)$'

# R8 is located in the 'builder' library.
AGP_MAVEN="https://dl.google.com/android/maven2/com/android/tools/build/builder"

def parse_options():
  parser = argparse.ArgumentParser(description='Tag R8 Versions')
  parser.add_argument(
      '--branch',
      help='The R8 branch to tag versions on, eg, origin/3.0')
  parser.add_argument(
      '--agp',
      help='The AGP to compute the tag for, eg, 4.2.0-beta03')
  parser.add_argument(
      '--dry-run',
      default=False,
      action='store_true',
      help='Print the state changing commands without running them.')
  return parser.parse_args()

def run(options, cmd):
  print(' '.join(cmd))
  if not options.dry_run:
    subprocess.check_call(cmd)

def main():
  args = parse_options()
  if args.branch:
    tag_r8_branch(args.branch, args)
  elif args.agp:
    tag_agp_version(args.agp, args)
  else:
    print("Should use a top-level option, such as --branch or --agp.")
    return 1
  return 0

def prepare_print_version(dist, temp):
  wrapper_file = os.path.join(
      utils.REPO_ROOT,
      'src/main/java/com/android/tools/r8/utils/PrintR8Version.java')
  cmd = [
    jdk.GetJavacExecutable(),
    wrapper_file,
    '-d', temp,
    '-cp', dist,
  ]
  utils.PrintCmd(cmd)
  subprocess.check_output(cmd)
  return temp

def get_tag_info_on_origin(tag):
  output = subprocess.check_output(
      ['git', 'ls-remote', '--tags', 'origin', tag]).decode('utf-8')
  if len(output.strip()) == 0:
    return None
  return output

def tag_agp_version(agp, args):
  tag = 'agp-%s' % agp
  result = get_tag_info_on_origin(tag)
  if result:
    print('Tag %s is already present' % tag)
    print(result)
    subprocess.call(['git', 'show', '--oneline', '-s', tag])
    return 0
  with utils.TempDir() as temp:
    url = "%s/%s/builder-%s.jar" % (AGP_MAVEN, agp, agp)
    jar = os.path.join(temp, "agp.jar")
    try:
      urllib.request.urlretrieve(url, jar)
    except urllib.error.HTTPError as e:
      print('Could not find jar for agp %s' % agp)
      print(e)
      return 1
    print_version_helper = prepare_print_version(utils.R8_JAR, temp)
    output = subprocess.check_output([
      jdk.GetJavaExecutable(),
      '-cp', ':'.join([jar, print_version_helper]),
      'com.android.tools.r8.utils.PrintR8Version'
    ]).decode('utf-8')
    version = output.split(' ')[0]
    run(args, ['git', 'tag', '-f', tag, '-m', tag, '%s^{}' % version])
    run(args, ['git', 'push', 'origin', tag])

def tag_r8_branch(branch, args):
  if not branch.startswith('origin/'):
    print('Expected branch to start with origin/')
    return 1
  output = subprocess.check_output([
    'git', 'log', '--pretty=format:%H\t%s', '--grep', VERSION_EXP, branch
  ]).decode('utf-8')
  for l in output.split('\n'):
    (hash, subject) = l.split('\t')
    m = re.search('Version (.+)', subject)
    if not m:
      print('Unable to find a version for line: %s' % l)
      continue
    version = m.group(1)
    result = get_tag_info_on_origin(version)
    if not result:
      run(args, ['git', 'tag', '-a', version, '-m', version, hash])
      run(args, ['git', 'push', 'origin', version])
  if args.dry_run:
    print('Dry run complete. None of the above have been executed.')


if __name__ == '__main__':
  sys.exit(main())
